<!--
 * @Description: ------------ fileDescription -----------
 * @Author: snows_l snows_l@163.com
 * @Date: 2024-08-05 12:46:00
 * @LastEditors: snows_l snows_l@163.com
 * @LastEditTime: 2025-01-20 12:37:47
 * @FilePath: \BLOG\src\views\home\index.vue
-->
<template>
  <div class="home-warp" :class="{ 'm-home-warp': isMobi }">
    <div class="first-screen" :style="{ backgroundImage: `url(${state.bgImg})` }">
      <img :src="state.bgImgUrl" style="width: 100%; height: 100%; object-fit: cover" />
      <div class="content-warp" :class="{ showContent: state.isShowContent }">
        <img class="avatar pointer" :src="state.avatar" @click="handleTo('/about/me')" />
        <div class="saying">
          <div class="saying-text">
            <span class="saying-icon">“</span>
            <span class="saying-words text">{{ state.saying }}</span>
            <span class="saying-write">|</span>
            <span class="saying-icon">”</span>
          </div>
          <h5 class="text" style="margin-top: 15px">Hello~ I'm snows_l</h5>
        </div>
        <div class="author-info">
          <div class="info-item tool-btn" :class="{ 'm-tool-btn': isMobi }" @click="handleToggleHomeBg('pre')">
            <img class="btn" src="@/assets/images/icon/pre.png" alt="" srcset="" />
          </div>
          <div class="info-out-warp-scroll">
            <div class="info-item-out-warp" :class="{ 'is-tool-next': state.isToolNext }">
              <div class="info-item-warp" v-for="(infoitemList, index) in infoList" :key="index">
                <div v-for="(item, index) in infoitemList" :key="index" class="info-item" :class="item.class" :data-tip="item.kbnTip" @click="handleInfo(item)">
                  <template v-for="img in item.imgs">
                    <img class="img" :class="img.class" :src="img.img" alt="" srcset="" />
                  </template>
                </div>
              </div>
            </div>
          </div>
          <div class="info-item tool-btn" :class="{ 'm-tool-btn': isMobi }" @click="handleToggleHomeBg('next')">
            <img class="btn" src="@/assets/images/icon/next.png" alt="" srcset="" />
          </div>
        </div>
      </div>
      <div class="bottom-down" @click="handleMoveToNext">
        <IconDown></IconDown>
      </div>
      <div class="bottom-bg"></div>
      <div class="bottom-bg1"></div>
      <div class="bottom-bg1"></div>
      <div class="transition-warp"></div>
    </div>
    <div class="other-content-warp">
      <Notice class="notice" v-if="isMobi" :class="{ 'm-notice': isMobi }"></Notice>
      <div class="flex-warp">
        <div class="content-center">
          <Notice class="notice" v-if="!isMobi" :class="{ 'm-notice': isMobi }"></Notice>
          <div class="other-content" v-if="!isMobi">
            <div class="other-content-item">
              <div class="article-title-warp">
                <img class="article-icon" src="@/assets/images/common/article.png" alt="" />
                <h2 class="content-title">ARTICLE</h2>
              </div>
              <div class="article-warp" v-if="state.articleList && state.articleList.length > 0">
                <div
                  class="article-item kbn-custom intersection-observer hover-shadow"
                  :data-tip="item.title.length > 16 ? '你想要阅读的文章“' + item.title.substring(0, 16) + '...”这篇文章吗？' : '你想要阅读的文章“' + item.title + '”这篇文章吗？'"
                  :class="item.isPreview === 1 ? 'is-preview' : ''"
                  v-for="(item, index) in state.articleList"
                  :key="index">
                  <div class="img-left item-warp" v-if="index % 2 === 0">
                    <div class="cover-img-warp pointer" @click="handleArticle(item)">
                      <LImg class="cover-img" :size="isMobi ? '120px' : '160px'" :src="item.cover" :fit="isMobi ? 'contain' : ''" :isUnPreview="true" />
                    </div>
                    <div class="item-content">
                      <div class="create-time">
                        <div class="time-warp">
                          <IconCalendar class="iconfont"></IconCalendar>
                          <span>发布于：</span>
                          <span class="time">{{ item.createTime }}</span>
                        </div>
                      </div>
                      <div class="article-title pointer" @click="handleArticle(item)">
                        {{ item.title }}
                      </div>
                      <div class="auth-info-warp">
                        <div>
                          <img :src="state.avatar" alt="" />
                          <span>snows_l</span>
                        </div>
                        <div>
                          <IconHot class="iconfont"></IconHot>
                          <span>{{ item.readCount || 0 }}</span>
                        </div>
                        <div>
                          <IconLike :size="18" class="iconfont" />
                          <span>{{ item.shareCount || 0 }}</span>
                        </div>
                        <div>
                          <IconComment :size="19" class="iconfont"></IconComment>
                          <span>{{ item.commentCount || 0 }}</span>
                        </div>
                        <div class="pointer" data-tip="点击 可直接阅览" v-if="item.isPreview === 1" @click="handleView(item)">
                          <IconPreview class="iconfont" :size="18"></IconPreview>
                          <span class="" style="font-size: 12px">预览</span>
                        </div>
                      </div>
                      <div class="article-des text">
                        {{ item.subTitle }}
                      </div>
                      <div class="label-warp">
                        <div class="type pointer hover-shadow" @click="handleType(item.type)">
                          <span class="icon-warp">
                            <IconType class="iconfont"></IconType>
                          </span>
                          <span class="lable" :style="{ 'background-color': 'var(--theme-light-color-2)' }">
                            {{ state.articleTypeList.find(v => v.value == item.type)?.label || '未知类型' }}
                          </span>
                        </div>
                        <div class="label-item pointer hover-shadow" @click="handleCategory(label)" v-for="(label, index) in item.labels" :key="index">
                          <span class="icon-warp">
                            <IconLabel class="iconfont" :size="'14px'"></IconLabel>
                          </span>
                          <span class="lable" :style="{ 'background-color': colorMap[index] }">{{ label }}</span>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="img-right item-warp" v-else>
                    <div class="item-content">
                      <div class="create-time">
                        <div class="time-warp">
                          <IconCalendar class="iconfont"></IconCalendar>
                          <span>发布于：</span>
                          <span class="time">{{ item.createTime }}</span>
                        </div>
                      </div>
                      <div class="article-title pointer" @click="handleArticle(item)">
                        {{ item.title }}
                      </div>
                      <div class="auth-info-warp">
                        <div>
                          <img :src="state.avatar" alt="" />
                          <span>snows_l</span>
                        </div>
                        <div>
                          <IconHot class="iconfont"></IconHot>
                          <span>{{ item.readCount || 0 }}</span>
                        </div>
                        <div>
                          <IconLike :size="18" class="iconfont" />
                          <span>{{ item.shareCount || 0 }}</span>
                        </div>
                        <div>
                          <IconComment :size="19" class="iconfont"></IconComment>
                          <span>{{ item.commentCount || 0 }}</span>
                        </div>
                        <div class="pointer" data-tip="点击 可直接阅览" v-if="item.isPreview === 1" @click="handleView(item)">
                          <IconPreview class="iconfont" :size="18"></IconPreview>
                          <span class="" style="font-size: 12px">预览</span>
                        </div>
                      </div>
                      <div class="article-des text">
                        {{ item.subTitle }}
                      </div>
                      <div class="label-warp">
                        <div class="type pointer" @click="handleType(item.type)">
                          <span class="icon-warp">
                            <IconType class="iconfont"></IconType>
                          </span>
                          <span class="lable" :style="{ 'background-color': 'var(--theme-light-color-2)' }">
                            {{ state.articleTypeList.find(v => v.value == item.type)?.label || '未知类型' }}
                          </span>
                        </div>
                        <div class="label-item pointer" @click="handleCategory(label)" v-for="(label, index) in item.labels" :key="index">
                          <span class="icon-warp">
                            <IconLabel class="iconfont" :size="'14px'"></IconLabel>
                          </span>
                          <span class="lable" :style="{ 'background-color': colorMap[index] }">{{ label }}</span>
                        </div>
                      </div>
                    </div>
                    <div class="cover-img-warp pointer" @click="handleArticle(item)">
                      <LImg class="cover-img" :size="isMobi ? '120px' : '160px'" :src="item.cover" :isUnPreview="true" />
                    </div>
                  </div>
                </div>
              </div>

              <div class="no-article" v-else>
                <Empty :text="'暂无文章，期待您的分享~'" :loadingText="'文章正在拼命加载中...'" :loading="state.loading" />
              </div>
            </div>
          </div>
          <div class="other-content m-other-content" v-else>
            <div class="other-content-item">
              <div class="article-title-warp">
                <img class="article-icon" src="@/assets/images/common/article.png" alt="" />
                <h2 class="content-title">ARTICLE</h2>
                <div class="article-warp" v-if="state.articleList && state.articleList.length > 0">
                  <div
                    class="article-item kbn-custom intersection-observer hover-shadow"
                    :data-tip="item.title.length > 16 ? '你想要阅读“' + item.title.substring(0, 16) + '...”这篇文章吗？' : '你想要阅读“' + item.title + '”这篇文章吗？'"
                    v-for="(item, index) in state.articleList"
                    :key="index">
                    <div class="img-left item-warp">
                      <div class="cover-img-warp pointer" @click="handleArticle(item)">
                        <LImg class="cover-img" :size="isMobi ? '120px' : '160px'" :src="item.cover" :isUnPreview="true" />
                      </div>
                      <div class="item-content">
                        <div class="create-time">
                          <div class="time-warp">
                            <IconCalendar class="iconfont"></IconCalendar>
                            <span>发布于：</span>
                            <span class="time">{{ item.createTime }}</span>
                          </div>
                        </div>
                        <div class="article-title pointer" @click="handleArticle(item)">
                          {{ item.title }}
                        </div>
                        <div class="auth-info-warp">
                          <div>
                            <img :src="state.avatar" vertical-align="middle" alt="" />
                            <span>snows_l</span>
                          </div>
                          <div>
                            <IconHot class="iconfont"></IconHot>
                            <span>{{ item.readCount || 0 }}</span>
                          </div>
                          <div>
                            <IconLike :size="18" class="iconfont" />
                            <span>{{ item.shareCount || 0 }}</span>
                          </div>
                          <div>
                            <IconComment :size="18" class="iconfont"></IconComment>
                            <span>{{ item.commentCount || 0 }}</span>
                          </div>
                          <div class="pointer" data-tip="点击 可直接阅览" v-if="item.isPreview === 1" @click="handleView(item)">
                            <IconPreview class="iconfont" :size="18"></IconPreview>
                            <span class="" style="font-size: 12px">预览</span>
                          </div>
                        </div>
                        <div class="article-des text">
                          {{ item.subTitle }}
                        </div>
                        <div class="label-warp">
                          <div class="type pointer" @click="handleType(item.type)">
                            <span class="icon-warp">
                              <IconType class="iconfont"></IconType>
                            </span>
                            <span class="lable" :style="{ 'background-color': 'var(--theme-light-color-2)' }">
                              {{ state.articleTypeList.find(v => v.value == item.type)?.label || '未知类型' }}
                            </span>
                          </div>
                          <div class="label-item pointer" @click="handleCategory(label)" v-for="(label, index) in item.labels" :key="index">
                            <span class="icon-warp">
                              <IconLabel class="iconfont" :size="'14px'"></IconLabel>
                            </span>
                            <span class="lable" :style="{ 'background-color': colorMap[index] }">{{ label }}</span>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="m-no-article" v-else>
                  <Empty :text="'暂无文章，等待作者更新~'" :loadingText="'文章正在拼命加载中...'" :loading="state.loading" />
                </div>
              </div>
            </div>
          </div>

          <LoadingMore
            v-if="store.projectConfig.pageType == 'more'"
            :loading="state.loading"
            :hasMore="state.isMore"
            :length="state.articleList.length"
            @loadMore="handleLoadMore"></LoadingMore>
          <CustomPage v-else :page="state.page" @change="handlePageChange" :loading="state.loading" scorllTop="content-center"></CustomPage>
        </div>
        <div class="slider-warp" v-if="!state.isMobile || isMobi">
          <div class="position-warp">
            <div class="auth-warp slider-item-warp" :class="{ 'intersection-observer': isMobi }">
              <div class="auth-content-warp">
                <img class="avatar pointer" :src="state.avatar" @click="handleTo('/about/me')" />
                <div class="mingyan text" style="font-size: 18px">snows_l</div>
                <div class="mingyan text">渔得鱼心满意足，樵得樵眼笑眉舒！</div>
                <div class="article-total">
                  <div class="article-total-item">
                    <div class="label">📚 文章总数</div>
                    <div class="num">{{ state.page.total }}</div>
                  </div>
                  <div class="article-total-item">
                    <div class="label">📒 分类</div>
                    <div class="num">{{ state.articleTypeList.length || 0 }}</div>
                  </div>
                  <div class="article-total-item">
                    <div class="label">🔖 标签</div>
                    <div class="num">{{ state.lebels || 0 }}</div>
                  </div>
                </div>
                <div class="code-store">
                  <img @click="handleToCodeStore(1)" class="icon-code link pointer" data-tip="我的github" src="@/assets/images/icon/github.svg" alt="" />
                  <img @click="handleToCodeStore(2)" class="icon-code gitlab link pointer" data-tip="我的gitlab" src="@/assets/images/icon/gitlab.png" alt="" />
                  <img @click="handleToCodeStore(3)" class="icon-code link pointer" data-tip="我的gitee" src="@/assets/images/icon/gitee.svg" alt="" />
                  <img @click="handleToCodeStore(4)" class="icon-code csdn link pointer" data-tip="我的CSDN" src="@/assets/images/icon/csdn.png" alt="" />
                </div>
              </div>
            </div>
            <div class="visit-info slider-item-warp" :class="{ 'intersection-observer': isMobi }" v-show="state.visit.ip">
              <div class="slider-title">
                💻 访问信息
                <div class="mac-style"></div>
              </div>
              <div class="visit-content-warp">
                <img class="tianqi-icon" :src="getCurrentTianqiImg(state.visit.tq)" alt="" />
                <div class="visit-item-warp">
                  <div class="visit-item">
                    <div class="visit-label">📅 日期：</div>
                    <div class="visit-value text">{{ state.visit.week }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">🏙 IP：</div>
                    <div class="visit-value text" v-if="state.visit.ip.length < 15">{{ state.visit.ip }}</div>

                    <div class="visit-value text" v-else>
                      <ToolTip :content="state.visit.ip" :placement="'bottom'">
                        <div class="text" style="text-wrap: nowrap; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%">
                          {{ state.visit.ip }}
                        </div>
                      </ToolTip>
                    </div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">🌃 城市：</div>
                    <div class="visit-value text">{{ state.visit.location }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">🌐 浏览器：</div>
                    <div class="visit-value text">{{ state.visit.browser }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">📱 平台：</div>
                    <div class="visit-value text">{{ state.visit.system }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">🌡 气温：</div>
                    <div class="visit-value text">{{ state.visit.low }} ~ {{ state.visit.high }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">☁️ 天气：</div>
                    <div class="visit-value text">{{ state.visit.tq }}</div>
                  </div>
                  <div class="visit-item">
                    <div class="visit-label">🌬️ 风力：</div>
                    <div class="visit-value text">{{ state.visit.fl }} {{ state.visit.fengxiang }}</div>
                  </div>
                  <div class="visit-tip text" v-if="state.visit.tip">⏰ {{ state.visit.tip }}</div>
                </div>
              </div>
            </div>

            <div class="hot-article slider-item-warp" :class="{ 'intersection-observer': isMobi }">
              <div class="slider-title">
                🔥 热门文章
                <div class="mac-style"></div>
              </div>
              <div class="hot-article-item-warp" v-if="state.hotArticleList.length > 0">
                <div class="hot-article-item hover-shadow" @click="handleArticle(item)" v-for="(item, index) in state.hotArticleList" :key="index">
                  <LImg class="cover-img" :src="item.cover" :isUnPreview="true" />
                  <div class="info">
                    <div class="article-title">{{ item.title }}</div>
                    <div class="h">
                      <IconHot class="iconfont"></IconHot>
                      <span class="num">{{ item.readCount || 0 }}</span>
                      - {{ item.createTime }}
                    </div>
                  </div>
                  <div class="top" :class="'top-' + (index + 1)">{{ index + 1 }}</div>
                </div>
              </div>
              <div class="m-no-article" v-else>
                <Empty :text="'暂无热门文章，期待您的分享~'" :loadingText="'热门文章正在拼命加载中...'" :loading="state.topArticleLoading" />
              </div>
            </div>

            <div class="tiangou-log-warp slider-item-warp" :class="{ 'intersection-observer': isMobi }">
              <div class="slider-title">
                (❁´◡`❁) 舔狗日记
                <div class="mac-style"></div>
              </div>
              <div class="content-warp">
                <div class="content text">{{ state.dog }}</div>
              </div>
              <div class="buttom-btn pointer kbn-custom" data-tip="换一个 舔(❁´◡`❁)" @click="getDog()">换一个</div>
            </div>

            <div class="label-warp slider-item-warp" :class="{ 'intersection-observer': isMobi }">
              <div class="slider-title">
                🔖 我的标签
                <div class="mac-style"></div>
              </div>
              <div class="label-item-warp">
                <div class="lebel-content-warp" v-if="state.labelList.length > 0">
                  <div
                    class="my-label-item pointer hover-shadow"
                    :style="{ border: '1px solid ' + item.color }"
                    @click="hanldeLable(item)"
                    v-for="item in state.labelList"
                    :key="item.label">
                    <span class="icon-warp">
                      <IconLabel :size="'14px'" />
                    </span>
                    <span class="lable" :style="{ 'background-color': item.color }">{{ item.label }}</span>
                  </div>
                </div>
                <div class="m-no-label" v-else>
                  <Empty :text="'暂无标签，快去添加吧~'" :loadingText="'标签正在加载中...'" :loading="state.loableLoading" />
                </div>
              </div>
            </div>

            <div class="visit-total slider-item-warp" :class="{ 'intersection-observer': isMobi }">
              <div class="slider-title">
                📈 关于/统计
                <div class="mac-style"></div>
              </div>
              <div class="visit-total-content pointer" @click="handleTo('/about/me')">
                <div class="visit-total-item total">
                  <div class="label">🍦 今天访问</div>
                  <div class="num">{{ state.blogVisitTotal.today || 1 }}</div>
                </div>
                <div class="visit-total-item total">
                  <div class="label">🍧 昨天访问</div>
                  <div class="num">{{ state.blogVisitTotal.yeasterday || 0 }}</div>
                </div>
                <div class="visit-total-item total">
                  <div class="label">🍨 当月访问</div>
                  <div class="num">{{ state.blogVisitTotal.currentMonth || 0 }}</div>
                </div>
                <div class="visit-total-item total">
                  <div class="label">🧁 总访问量</div>
                  <div class="num">{{ state.blogVisitTotal.sum || 0 }}</div>
                </div>
                <div class="visit-total-item">
                  <div class="label">🌈 运行时间</div>
                  <div class="time-warp">
                    <IconHour24 class="time-24" />
                  </div>
                  天
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { getArticleList, getTopArticle } from '@/api/article';
import { getBlogVisit, getDict } from '@/api/common';
import Notice from '@/components/Notice/index.vue';
import useIntersectionObserver from '@/hooks/useIntersectionObserver';
import useResize from '@/hooks/useResize';
import { useAppStore } from '@/store/app';
import { changeBgImg, getImgIcon, getOnlineImgUrl, getQQAvatar, isMobile } from '@/utils/common';
import { getRandomColor, getDark } from '@/utils/theme';
import axios from 'axios';
import moment from 'moment';
import { onMounted, onUnmounted, reactive } from 'vue';
import { useRouter } from 'vue-router';

useIntersectionObserver();

const { isMobi } = useResize();
const router = useRouter();
const store = useAppStore();

const saying = '我见众生皆草木，唯你是青山。';

const state = reactive({
  saying: '',
  isShowContent: false,
  avatar: getQQAvatar(),
  loading: false,
  isMore: true,
  isToolNext: false,
  articleList: [],
  articleTypeList: [],
  lebels: 0,
  bgImg: '',
  bgImgUrl: changeBgImg(),
  isMobile: isMobile(1260),
  visit: {
    time: '',
    week: '',
    ip: '',
    location: '',
    browser: '',
    system: '',
    low: '',
    high: '',
    tq: '',
    fl: '',
    fengxiang: '',
    tip: ''
  },
  hotArticleList: [],
  blogVisitTotal: {
    today: 0,
    yeasterday: 0,
    currentMonth: 0,
    sum: 0
  },
  dog: '你跟他已经醒了吧？我今天捡垃圾挣了一百多，明天给你打过去。你快点休息吧，我明天叫你起床给你点外卖、买烟、给你点你最喜欢的奶茶。晚上我会继续去摆地摊的，你不用担心我烦你床只有那么大睡不下三个，你要好好照顾好自己，不要让他抢你被子，我永远爱你',
  page: {
    page: 1,
    size: 10,
    total: 0
  },
  labelList: [],
  autoToggleBgTimer: null,
  loableLoading: false,
  topArticleLoading: false
});

const colorMap = {
  0: getRandomColor(),
  1: getRandomColor(),
  2: getRandomColor(),
  3: getRandomColor(),
  4: getRandomColor(),
  5: getRandomColor(),
  6: getRandomColor(),
  7: getRandomColor(),
  8: getRandomColor(),
  9: getRandomColor()
};

import iconEmail from '@/assets/images/icon/mail.png';
import iconQQ from '@/assets/images/icon/qq.png';
import iconWeixin from '@/assets/images/icon/weixin.png';

const infoList = [
  [
    {
      class: 'kbn-qq',
      imgs: [{ img: iconQQ }],
      kbnTip: 'QQ: 37523953',
      link: false,
      fnQuery: 'qq'
    },
    {
      class: 'weixin-content kbn-weixin',
      imgs: [
        { class: 'weixin-icon', img: iconWeixin },
        { class: 'weinxin-qrcode', img: getOnlineImgUrl('/imgs/common/wechat-qrcode.png') }
      ],
      kbnTip: 'WeChat: snows__l',
      link: false,
      fnQuery: 'weixin'
    },
    {
      class: 'kbn-email',
      imgs: [{ img: iconEmail }],
      kbnTip: 'Email: snows_l@163.com',
      link: true,
      fnQuery: 'email'
    }
  ]
];

// 获取天气信息
axios.get('https://api.vvhan.com/api/visitor.info').then(res => {
  if (res.data.success) {
    state.visit = res.data;
  }
});

// 舔狗日记
const getDog = () => {
  axios.get('https://v2.api-m.com/api/dog').then(res => {
    state.dog = res.data.data;
  });
};
getDog();

// 获取热门文章
state.topArticleLoading = true;
getTopArticle()
  .then((res: any) => {
    if (res.code === 200) {
      state.hotArticleList = res.data;
      state.hotArticleList.forEach(item => {
        item.cover = import.meta.env.VITE_CURRENT_ENV == 'dev' ? import.meta.env.VITE_DEV_BASE_SERVER + item.cover : store.projectConfig.bsServerUrl + item.cover;
        item.createTime = item.createTime && moment(item.createTime).format('YYYY-MM-DD');
      });
    }
  })
  .finally(() => {
    state.topArticleLoading = false;
  });

// // 获取博客访问统计
const getBlogVisitFn = () => {
  getBlogVisit().then(res => {
    if (res.code === 200) {
      state.blogVisitTotal = res.data;
    }
  });
};
getBlogVisitFn();

// 获取我的标签
const getDictFn = () => {
  state.loableLoading = true;
  getDict({ dictType: 'blog_label' })
    .then(res => {
      if (res.code === 200) {
        state.labelList = res.data.map(item => {
          return {
            label: item.label,
            color: getRandomColor()
          };
        });
      }
    })
    .finally(() => {
      state.loableLoading = false;
    });
};
getDictFn();

// 点击我的标签  跳转到分类列表
const hanldeLable = item => {
  router.push({
    path: '/article/category',
    query: {
      type: 4,
      category: item.label
    }
  });
};

// 代码仓库
const handleToCodeStore = (type: number) => {
  if (type === 1) {
    window.open('https://github.com/snows-l', '_blank');
  } else if (type === 2) {
    window.open('https://gitlab.com/snows_l', '_blank');
  } else if (type === 3) {
    window.open('https://gitee.com/snows_l', '_blank');
  } else if (type === 4) {
    window.open('https://blog.csdn.net/snows_l?type=blog', '_blank');
  }
};

// 获取当前天气icon
const getCurrentTianqiImg = (tq: string) => {
  let img = '阴.svg';
  const tianqis = ['晴', '多云', '阴', '小雨', '中雨', '大雨', '阵雨', '暴雨', '小雪', '中雪', '大雪', '雨夹雪', '雾'];
  if (tq) {
    tianqis.forEach(item => {
      if (tq.includes(item)) {
        img = item + '.svg';
      }
    });
  }
  return getImgIcon(img);
};

// 跳转关于我
const handleTo = (path: string) => {
  router.push({
    path
  });
};

// 获取文章列表
const getArticleListFn = scorllTopCallback => {
  state.loading = true;
  getArticleList(state.page)
    .then(res => {
      if (res.code === 200) {
        res.data.forEach(item => {
          item.createTime = moment(item.createTime).format('YYYY-MM-DD HH:mm:ss');
          item.cover = import.meta.env.VITE_CURRENT_ENV == 'dev' ? import.meta.env.VITE_DEV_BASE_SERVER + item.cover : store.projectConfig.bsServerUrl + item.cover;
          item.subTitle = item.subTitle.replace(/&#39;/g, "'");
          item.labels = item.labels && item.labels.split(',');
        });
        if (store.projectConfig.pageType == 'more') {
          state.articleList = [...state.articleList, ...res.data];
        } else {
          state.articleList = res.data;
        }
        state.page.total = res.total;
        if (res.data.length === 0 || state.articleList.length >= res.total) {
          state.isMore = false; // 已经没有更多数据了
        }
        scorllTopCallback && scorllTopCallback();
      }
    })
    .catch(() => {
      state.isMore = false;
    })
    .finally(() => {
      state.loading = false;
    });
};
getArticleListFn();

// 打字效果输出saying
let intervalTimer: number | null = null;
const inputSaying = () => {
  let index = 0;
  intervalTimer = setInterval(() => {
    if (index === saying.length) {
      clearInterval(intervalTimer);
      return;
    }
    state.saying += saying[index];
    index++;
  }, 120);
};

// 加在更多
const handleLoadMore = () => {
  state.loading = true;
  state.page.page++;
  getArticleListFn();
};

// 分页改变
const handlePageChange = (page: number, size: number, scorllTopCallback: Function) => {
  state.page.page = page;
  state.page.size = size;
  getArticleListFn(scorllTopCallback);
};

// 切换首页背景
const handleToggleHomeBg = (type: string) => {
  if (type === 'next') {
    if (store.bgIndex == store.bgImgMaxLen) {
      store.SET_BG_INDEX(1);
    } else {
      store.SET_BG_INDEX(store.bgIndex + 1);
    }
  } else {
    if (store.bgIndex == 1) {
      store.SET_BG_INDEX(store.bgImgMaxLen);
    } else {
      store.SET_BG_INDEX(store.bgIndex - 1);
    }
  }
  state.bgImgUrl = changeBgImg(store.bgIndex);
};

// infoMap
const infoMap = {
  qq: 'mqqwpa://im/proxy?src_type=web&qq_number=37523953',
  email: 'mailto:snows_l@163.com'
};
// 跳转到QQ
const toQQ = () => {
  let system = {};
  const p = navigator.platform;
  system.win = p.indexOf('Win') == 0;
  system.mac = p.indexOf('Mac') == 0;
  system.x11 = p == 'X11' || p.indexOf('Linux') == 0;
  if (system.win || system.mac || system.xll) {
    //如果是电脑跳转到
    window.open('http://wpa.qq.com/msgrd?v=3&uin=37523953&site=qq&menu=yes');
  } else {
    //如果是手机,跳转到
    window.open('mqqwpa://im/chat?chat_type=wpa&uin=37523953&version=1&src_type=web');
  }
};

// 点击名言下的tool
const handleInfo = (item: { class: string; imgs: any[]; kbnTip: string; title: string; link: boolean; fnQuery: string }) => {
  if (item.link) {
    window.open(item.link, '_blank');
  } else {
    if (item.fnQuery === 'qq') {
      toQQ();
    } else {
      infoMap[item.fnQuery] && window.open(infoMap[item.fnQuery]);
    }
  }
};

// 获取文章类型
const getArticleTypeList = () => {
  getDict({ dictType: 'article_type' }).then(res => {
    if (res.code === 200) {
      state.articleTypeList = res.data;
      store.SET_ARTICLE_DICT(res.data);
    }
  });
};

// huoqu blog_label
const getBlogLabel = () => {
  getDict({ dictType: 'blog_label' }).then(res => {
    if (res.code === 200) {
      state.lebels = res.data.length;
    }
  });
};
getBlogLabel();

// perf 先看store有没有， 没有在请求
store.articleDict.length > 0 ? (state.articleTypeList = store.articleDict) : getArticleTypeList();

// 点击文章详情
const handleArticle = (row: any) => {
  router.push({
    path: '/article/detail',
    query: {
      id: row.id
    }
  });
};

// 点击阅览
const handleView = (row: any) => {
  let urlPrefix = store.projectConfig.blogUrl;
  window.open(urlPrefix + '/preview?id=' + row.id, '_blank');
};

// 点击文章类型
const handleType = (type: number) => {
  router.push({
    path: '/article/category',
    query: {
      type: type
    }
  });
};

// 点击文章分类
const handleCategory = (label: string) => {
  router.push({
    path: '/article/category',
    query: {
      type: 4,
      category: label
    }
  });
};

// 下一页
const handleMoveToNext = () => {
  if (document.getElementById('layout')) {
    document.getElementById('layout').scrollTop = document.getElementById('layout')?.clientHeight - 60;
  }
};

const resizeCallback = () => {
  state.isMobile = isMobile(1260);
};

let timer: null | number = null;
let timer2: null | number = null;
onMounted(() => {
  timer = setTimeout(() => {
    state.isShowContent = true;
  }, 400);

  timer2 = setTimeout(() => {
    inputSaying();
  }, 800);

  //监听localStorage变化
  window.addEventListener('resize', resizeCallback);
});

// 卸载 优化
onUnmounted(() => {
  if (timer) {
    clearTimeout(timer);
    timer = null;
  }
  if (timer2) {
    clearTimeout(timer2);
    timer2 = null;
  }
  if (intervalTimer) {
    clearInterval(intervalTimer);
    intervalTimer = null;
  }
  if (state.autoToggleBgTimer) {
    clearInterval(state.autoToggleBgTimer);
    state.autoToggleBgTimer = null;
  }
  window.removeEventListener('resize', resizeCallback);
});
</script>

<style lang="scss" scoped>
.home-warp {
  .first-screen {
    width: 100%;
    height: 100vh;
    position: relative;
    background-color: var(--bg-image-warp-color);
    .content-warp {
      max-width: 96%;
      width: 60%;
      margin: 0 auto;
      position: absolute;
      top: 25%;
      left: 50%;
      transform: translate(-50%, 0);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      opacity: 0;
      transition: top 0.8s ease-in, opacity 0.8s ease-in;
      .avatar {
        width: 120px;
        height: 120px;
        border-radius: 50%;
        border: rgba(144, 147, 153, 0.23) 5px solid;
        transition: all 1.2s ease-in-out;
      }
      .avatar:hover {
        border-width: 8px;
        transform: rotate(360deg);
      }
      .saying {
        width: 100%;
        max-width: 750px;
        min-width: 350px;
        padding: 20px 0;
        margin-top: 30px;
        border-radius: var(--border-radius-2);
        background-color: var(--bg-content-color);
        color: var(--text-color);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        .saying-icon {
          margin: 0 10px;
          font-size: 22px;
          font-weight: 800;
        }
        .saying-write {
          font-size: 16px;
          margin: 0 3px;
          font-weight: 600;
          animation: blink 1s infinite;
        }
        .saying-words {
          font-size: 16px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
      .author-info {
        display: flex;
        margin-top: 30px;
        align-items: center;
        justify-content: center;
        height: 80px;
        .info-out-warp-scroll {
          width: 230px;
          overflow: hidden;
          display: flex;
          justify-content: center;
          align-items: center;
          position: relative;
          height: 100%;
          .info-item-out-warp {
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top: 0;
            left: 0;
            height: 100%;
            transition: left 0.8s ease-in-out;
            .info-item-warp {
              width: 230px;
              display: flex;
              justify-content: center;
              align-items: center;
              height: 100%;
            }
          }
          .is-tool-next {
            left: -230px;
          }
        }
        .info-item {
          margin: 0 10px;
          cursor: url('@/assets/images/cursor/pointer.png'), auto;
          padding: 8px;
          border-radius: var(--border-radius-2);
          background-color: var(--bg-warp-color);
          display: flex;
          justify-content: center;
          align-items: center;
          width: 50px;
          height: 50px;
        }
        .tool-btn {
          margin: 0 5px;
        }
        .m-tool-btn {
          background-color: transparent;
          width: 30px !important;
        }
        .btn,
        img {
          width: 30px;
          height: 30px;
        }
        .weixin-content {
          width: 50px;
          height: 50px;
          transition: width 0.8s ease-in-out, height 0.8s ease-in-out;
          overflow: hidden;
          .weinxin-qrcode {
            display: none;
          }
        }
        .weixin-content:hover {
          width: 80px !important;
          height: 80px;
          .weixin-icon {
            display: none;
          }
          .weinxin-qrcode {
            display: block;
            width: 64px;
            height: 64px;
          }
        }
      }
    }
    .showContent {
      top: 25%;
      opacity: 1;
    }
    .bottom-bg {
      height: 65px;
      position: absolute;
      bottom: 0;
      width: 400%;
      left: -236px;
      z-index: 4;
      transition-duration: 0.4s, 0.4s;
      animation: move2 20s linear infinite;
      background-image: url('@/assets/images/common/wave1.png');
    }
    .bottom-bg1 {
      position: absolute;
      height: 80px;
      width: 400%;
      left: 0;
      bottom: 0;
      z-index: 3;
      opacity: 1;
      transition-duration: 0.4s, 0.4s;
      animation: move2 40s linear infinite;
      background-image: url('@/assets/images/common/wave2.png');
    }
    .transition-warp {
      position: absolute;
      bottom: -80px;
      height: 80px;
      width: 100%;
      left: 0;
      z-index: 3;
      opacity: 1;
      background: linear-gradient(to bottom, rgba(255, 255, 255, 0.6) 60%, rgba(255, 255, 255, 0.1));
      pointer-events: none;
    }
    .bottom-down {
      position: absolute;
      bottom: 80px;
      left: calc(50% - 40px);
      animation: bottomAnimation 1.6s infinite;
    }
  }
  .other-content-warp {
    padding-top: 40px;
    background-color: var(--under-background);
    .notice {
      max-width: var(--content-max-width);
      margin: 0 auto;
      max-height: 120px;
    }
    .flex-warp {
      max-width: 1240px;
      margin: 0 auto;
      display: flex;
      justify-content: center;
      .content-center {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
      }
      .slider-warp {
        margin-top: 44px;
        width: 300px;
        margin-left: 20px;
        .position-warp {
          position: sticky;
          top: 70px;
          padding-bottom: 20px;
          .slider-item-warp {
            width: 100%;
            box-shadow: var(--box-shadow);
            border-radius: var(--border-radius-1);
            position: relative;
            overflow: hidden;
            .slider-title {
              padding-left: 14px;
              height: 44px;
              font-size: 16px;
              line-height: 44px;
              border-bottom: 1px solid #ccc;
              color: #222;
            }
            .mac-style {
              content: ' ';
              position: absolute;
              -webkit-border-radius: 50%;
              border-radius: 50%;
              background: #fc625d !important;
              width: 11px;
              height: 11px;
              -webkit-box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
              box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b;
              float: right;
              right: 55px;
              top: 17px;
            }
          }
          .auth-warp {
            background-image: url('@/assets/images/bg/aside_author_image.jpg');
            background-size: 100% 30%;
            background-repeat: no-repeat;
            border-radius: var(--border-radius-1);
            .auth-content-warp {
              padding: 30px 20px;
              display: flex;
              flex-direction: column;
              align-items: center;
              background-image: linear-gradient(#ffffff00, #ebfcfd 40%, #caeafa 100%);
              .avatar {
                width: 100px;
                height: 100px;
                border-radius: 50%;
                border: rgba(144, 147, 153, 0.23) 3px solid;
              }
              .mingyan {
                margin-top: 10px;
                line-height: 30px;
                color: #333;
              }
              .article-total {
                margin-top: 30px;
                display: flex;
                justify-content: space-around;
                .article-total-item {
                  margin: 0 10px;
                  display: flex;
                  flex-direction: column;
                  align-items: center;
                  .label {
                    font-size: 14px;
                    margin-bottom: 10px;
                    color: #111;
                  }
                  .num {
                    font-size: 20px;
                    color: var(--theme-color);
                  }
                }
              }
              .code-store {
                margin-top: 20px;
                width: 100%;
                border-top: 1px solid #cacaca;
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 20px 10px 0 10px;
                .icon-code {
                  margin: 0 15px;
                  width: 30px;
                  height: 30px;
                  border-radius: 50%;
                }
                .gitlab {
                  width: 40px;
                  height: 40px;
                }
                .csdn {
                  height: 40px;
                }
              }
            }
          }
          .visit-info {
            margin-top: 20px;
            display: flex;
            flex-direction: column;
            background-image: linear-gradient(#ffffff00, #caf3f4 50%, #b4f6e2 100%);
            .visit-content-warp {
              padding: 40px 0 0 0;
              position: relative;
              background-size: 30% 30%;
              background-repeat: no-repeat;
              background-position: right;
              min-height: 285px;
              .tianqi-icon {
                width: 28%;
                height: 28%;
                position: absolute;
                top: 10px;
                right: 10px;
                animation: cloudAnimation 2s linear infinite;
              }
              .visit-item-warp {
                position: absolute;
                top: 40px;
                left: 0px;
                width: 100%;
                padding: 0 20px 20px 20px;
                z-index: 99;
              }
              .visit-item {
                color: #222;
                display: flex;
                justify-content: flex-start;
                margin: 10px 0;
                .visit-label {
                  text-align: left;
                  width: 90px;
                }
                .visit-value {
                  width: calc(100% - 90px);
                }
              }
              .visit-tip {
                margin-top: 20px;
                color: #222;
              }
            }
          }
          .hot-article {
            margin-top: 20px;
            background-color: #fff;
            .hot-article-item-warp {
              padding: 10px;
              .hot-article-item {
                position: relative;
                width: 100%;
                margin: 10px 0;
                border-radius: var(--border-radius-1);
                overflow: hidden;
                transition: opacity 0.8s ease-in-out;
                background-color: var(--bg-content-color);
                box-shadow: var(--box-shadow);
                padding-bottom: 10px;
                .cover-img {
                  width: 100%;
                  height: 120px;
                  transition: transform 0.8s ease-in-out;
                  &:hover {
                    transform: scale(1.1);
                  }
                }
                .info {
                  width: 100%;
                  height: 100%;
                  padding: 0px 10px;
                  margin-top: 10px;
                  .article-title {
                    color: var(--text-color);
                    // 两行显示省略号
                    display: -webkit-box;
                    -webkit-box-orient: vertical;
                    -webkit-line-clamp: 1;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: normal;
                    text-shadow: var(--text-shadow);
                    font-size: 16px;
                    margin: 5px 0;
                  }
                  .h {
                    display: flex;
                    align-items: center;
                  }
                  .num {
                    margin: 0 5px;
                    color: var(--theme-color);
                  }
                }
                .top {
                  // 右旋转45度
                  transform: rotate(45deg);
                  -webkit-transform: rotate(45deg);
                  position: absolute;
                  top: 10px;
                  right: -20px;
                  width: 80px;
                  height: 20px;
                  color: #fff;
                  text-align: center;
                  line-height: 20px;
                }
                .top-1 {
                  background-color: #ff183b;
                }
                .top-2 {
                  background-color: #ff5c38;
                }
                .top-3 {
                  background-color: rgb(242, 193, 16);
                }
              }
            }
          }
          .tiangou-log-warp {
            margin-top: 20px;
            background-color: #fff;
            .content-warp {
              padding: 20px;
              .content {
                color: #222;
                line-height: 32px;
                border: 1px solid #d3d5db;
                padding: 15px;
                background: #f2f6fc;
                border-bottom-left-radius: 15px 225px;
                border-bottom-right-radius: 20px 205px;
                border-top-left-radius: 28px 125px;
                border-top-right-radius: 100px 30px;
              }
            }
            .buttom-btn {
              padding-bottom: 20px;
              text-align: center;
              color: #222;
            }
          }
          .visit-total {
            margin-top: 20px;
            background-image: linear-gradient(#ffffff00, #e3f4f5 10%, #ffb384 100%);
            .visit-total-content {
              padding: 20px;
              .visit-total-item {
                display: flex;
                justify-content: space-between;
                align-items: center;
                position: relative;
                height: 60px;
                color: #222;

                .label,
                .num {
                  color: #222;
                  font-size: 18px;
                }
                .time-warp {
                  position: absolute;
                  top: -60px;
                  right: 40px;
                  width: 60px;
                  height: 120px;
                  padding: 60px 0 0 0;
                  animation: swing 1.3s ease-in-out infinite alternate;
                  display: flex;
                  .time-24 {
                    width: 60px;
                    height: 60px;
                  }
                }
              }
              .total {
                height: 30px;
              }
            }
          }
          .label-warp {
            margin-top: 20px;
            background-image: linear-gradient(#ffffff00, #e3f4f5 20%, #b3e7a3 100%);
            .lebel-content-warp {
              padding: 20px;
              display: flex;
              flex-wrap: wrap;
              .my-label-item {
                margin: 5px;
                color: #fff;
                display: flex;
                align-items: center;
                border-radius: var(--border-radius-3);
                overflow: hidden;
                .icon-warp,
                .lable {
                  height: 100%;
                  display: inline-block;
                }
                .icon-warp {
                  padding: 4px 6px 4px 8px;
                  background-color: transparent;
                  border-right: 1px solid var(--border-color) !important;
                  border-top-left-radius: var(--border-radius-3);
                  border-bottom-left-radius: var(--border-radius-3);
                }
                .lable {
                  color: #fff;
                  padding: 4px 6px 4px 10px !important;
                  font-size: 15px;
                  line-height: 14px;
                }
              }
            }
          }
        }
      }
    }

    .other-content {
      margin-top: 30px;
      max-width: var(--content-max-width);
      width: 100%;
      .other-content-item {
        .article-title-warp {
          .article-icon {
            width: 26px;
            height: 26px;
          }
          .content-title {
            margin-top: 10px;
            font-size: 20px;
            font-weight: 600;
            color: var(--text-color);
            text-shadow: var(--text-shadow);
          }
        }
        .article-item {
          margin: 24px 0;
          border-radius: var(--border-radius-2);
          width: 100%;
          height: 100%;
          overflow: hidden;
          box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
          &:last-child {
            margin-bottom: 0;
          }
          &:hover {
            .cover-img {
              transform: scale(1.2);
            }
          }
          .item-warp {
            display: flex;
            width: 100%;
          }
          .cover-img-warp {
            width: 450px;
            height: 280px;
            overflow: hidden;
            .cover-img {
              width: 100%;
              height: 100%;
              transition: transform 0.8s ease-in-out;
            }
          }

          .item-content {
            flex: 1;
            height: 280px;
            padding: 33px 30px;
            background-color: var(--bg-content-color);
            position: relative;
            .create-time {
              display: inline-block;
              align-items: center;
              height: 24px;
              font-size: 12px;
              padding: 2px 0px;
              // background-color: var(--theme-light-color-9);
              border-radius: 5px;
              color: var(--theme-color);
              .time-warp {
                height: 100%;
                display: flex;
                align-items: center;
                .iconfont {
                  font-size: 12px;
                  margin-right: 10px;
                }
              }
              // .type {
              //   height: 22px;
              //   border-radius: 5px;
              //   padding: 2px 4px;
              //   font-size: 12px;
              //   position: absolute;
              //   top: 48px;
              //   right: 30px;
              // }
            }
            .article-title {
              margin-top: 10px;
              height: 30px;
              font-size: 20px;
              line-height: 30px;
              cursor: url('@/assets/images/cursor/text.png'), auto;
              display: -webkit-box;
              -webkit-box-orient: vertical;
              -webkit-line-clamp: 1;
              overflow: hidden;
              text-overflow: ellipsis;
              text-align: left;
              color: var(--text-color);
            }
            .article-title:hover {
              color: var(--theme-color);
            }
            .auth-info-warp {
              height: 50px;
              display: flex;
              align-items: center;
              justify-content: space-between;
              div {
                display: flex;
                align-items: center;
                .iconfont {
                  margin-right: 10px;
                  font-size: 18px;
                  color: var(--theme-color);
                }
                .icon-yanjing {
                  font-size: 24px;
                }
                span {
                  font-size: 12px;
                  color: var(--text-color);
                }
              }
              img {
                width: 30px;
                height: 30px;
                border-radius: 50%;
                margin-right: 10px;
              }
            }
            .article-des {
              height: 64px;
              line-height: 21px;
              display: -webkit-box;
              -webkit-box-orient: vertical;
              -webkit-line-clamp: 3;
              overflow: hidden;
              text-overflow: ellipsis;
              color: var(--text-color-2);
            }
          }
          .label-warp {
            display: flex;
            align-items: center;
            justify-content: flex-start;
            flex-wrap: wrap;
            margin-top: 10px;
            .type {
              font-size: 12px;
              border-radius: 5px;
              margin-right: 15px;
              height: 20px;
              display: flex;
              align-items: center;
              overflow: hidden;
              margin-bottom: 2px;
              .icon-warp {
                padding: 1px 6px 1px 8px;
                border-right: 1px solid var(--border-color);
              }
            }
            .label-item {
              margin-right: 10px;
              font-size: 12px;
              display: flex;
              align-items: center;
              border-radius: var(--border-radius-1);
              overflow: hidden;
              height: 20px;
              margin-bottom: 2px;
            }
            .icon-warp,
            .lable {
              height: 100%;
              display: inline-block;
            }
            .icon-warp {
              padding: 3px 6px 3px 8px;
              background-color: #b3b0b0;
              border-right: 1px solid var(--border-color);
            }
            .lable {
              color: #fff;
              padding: 4px 10px 4px 6px !important;
              font-size: 12px;
              text-wrap: nowrap;
            }
          }
        }
      }
    }

    .m-other-content {
      max-width: var(--content-max-width-m);
      .item-warp {
        display: flex;
        flex-direction: column;
        height: auto !important;
        .cover-img-warp {
          width: 100% !important;
          height: 180px !important;
        }

        .item-content {
          height: 180px !important;
          padding: 20px 20px !important;
          .article-title {
            margin-top: 5px !important;
            height: 30px !important;
            line-height: 30px !important;
            font-size: 16px !important;
          }
        }
        .auth-info-warp {
          height: 30px !important;
          img {
            width: 20px !important;
            height: 20px !important;
          }
        }
        .article-des {
          height: 30px !important;
          line-height: 15px !important;
          font-size: 12px !important;
          -webkit-line-clamp: 2 !important;
        }
      }
    }
  }
}

.m-home-warp {
  .notice {
    max-width: var(--content-max-width-m) !important;
    margin: 0 auto;
  }
  .flex-warp {
    flex-direction: column-reverse !important;
    .slider-warp {
      width: var(--content-max-width-m) !important;
      margin: 0 auto !important;
      margin-top: 30px !important;
    }
    .hot-article {
      .cover-img {
        height: 30vw !important;
      }
    }
  }
}

@keyframes swing {
  0% {
    transform: rotate(18deg);
  }
  100% {
    transform: rotate(-18deg);
  }
}

// 光标闪烁效果动画
@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
// 背景动画
@keyframes move2 {
  100% {
    background-position: -100% 0;
  }
}
// 下滑按钮动画
@keyframes bottomAnimation {
  0% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(16px);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes cloudAnimation {
  0% {
    transform: translate(0px);

    opacity: 0.8;
  }
  50% {
    transform: translate(8px);
    opacity: 1;
  }
  100% {
    transform: translate(0px);
    opacity: 0.8;
  }
}
</style>
